package com.engine4cloud.tdf.supervision.service.impl;

import com.engine4cloud.tdf.common.core.constant.enums.AllAuditActionStatusEnum;
import com.engine4cloud.tdf.common.core.constant.enums.AuditBusinessTypeEnum;
import com.engine4cloud.tdf.common.core.exception.ValidateCodeException;
import com.engine4cloud.tdf.supervision.dto.SpAuditDTO;
import com.engine4cloud.tdf.supervision.dto.create.SpAuditResultCreateDTO;
import com.engine4cloud.tdf.supervision.dto.result.OutApplicationSettingResultDTO;
import com.engine4cloud.tdf.supervision.dto.result.SpOutApplicationResultDTO;
import com.engine4cloud.tdf.supervision.dto.update.SpAllPreActionUpdateDTO;
import com.engine4cloud.tdf.supervision.service.*;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
public class SpOutApplicationAuditServiceImpl implements SpOutApplicationAuditService {
    @Resource
    private SpAuditService auditService;
    @Resource
    private SpAuthorizeService authorizeService;
    @Resource
    private SpApproveService approveService;
    @Resource
    private SpFinishService finishService;
    @Resource
    private SpOutApplicationService outApplicationService;
    @Resource
    private OutApplicationSettingService outApplicationSettingService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean audit(SpAuditDTO dto) {
        SpOutApplicationResultDTO outApplication = Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        OutApplicationSettingResultDTO defaultSetting = Optional.ofNullable(outApplicationSettingService.findDefaultSetting())
                .orElseThrow(() -> new ValidateCodeException("外出配置数据不存在，请联系管理员"));

        //请假天数大于7天，还需要县局审批
        if (defaultSetting.getCountyExecute().compareTo(outApplication.getWcts()) < 0) {
            outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.VILLAGE_AUDIT));
            return auditService.villageAudit(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.VILLAGE_AUDIT));
        } else {
            outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.AUDIT));
            return auditService.audit(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.AUDIT));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refuse(SpAuditDTO dto) {
        Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.REFUSE));
        return auditService.refuse(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.REFUSE));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean authorize(SpAuditDTO dto) {
        SpOutApplicationResultDTO outApplication = Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        OutApplicationSettingResultDTO defaultSetting = Optional.ofNullable(outApplicationSettingService.findDefaultSetting())
                .orElseThrow(() -> new ValidateCodeException("外出配置数据不存在，请联系管理员"));

        //请假天数大于30天，还需要市局审批
        if (defaultSetting.getCityExecute().compareTo(outApplication.getWcts()) < 0) {
            outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.COUNTRY_AUTHORIZE));
            return authorizeService.countryAuthorize(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.COUNTRY_AUTHORIZE));
        } else {
            outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.AUTHORIZE));
            return authorizeService.authorize(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.AUTHORIZE));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean reject(SpAuditDTO dto) {
        Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.REJECT));
        return authorizeService.reject(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.REJECT));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean approve(SpAuditDTO dto) {
        Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.APPROVE));
        return approveService.approve(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.APPROVE));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean veto(SpAuditDTO dto) {
        Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.VETO));
        return approveService.veto(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.VETO));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean close(SpAuditDTO dto) {
        Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        //设置销假时间
        outApplicationService.close(dto.getLcbh());
        //结束流程
        outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.FINISH));
        return finishService.finish(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.FINISH));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(SpAuditDTO dto) {
        Optional.ofNullable(outApplicationService.getByBatch(dto.getLcbh()))
                .orElseThrow(() -> new ValidateCodeException("外出数据不存在"));

        outApplicationService.changeAction(new SpAllPreActionUpdateDTO(dto.getRybh(), dto.getLcbh(), AllAuditActionStatusEnum.CANCEL));
        return finishService.cancel(new SpAuditResultCreateDTO(dto, AuditBusinessTypeEnum.OUT_APPLICATION, AllAuditActionStatusEnum.CANCEL));
    }
}
